#ifdef _USE_DLL_SECURITY_


//****************************************************************************
//       INGENICO                                TDS 6.4.2                   
//============================================================================
//       FILE  CRYPTO.C                           (Copyright INGENICO 2008)   
//============================================================================
//  Created :       12-May-2008     Kassovic                                 
//  Last modified : 12-May-2008     Kassovic                                
//  Module : TRAINING                                                          
//                                                                          
//  Purpose :                                                               
//  Pin entry management:
//  !!! Security DLL must be loaded 3656xxxx.SGN inside the terminal but not
//      necessary under simulation.
//      Helpful component to manage secure schemes.
//      IAPP.lib + SEC.LIB must be implemented to link properly.  
//      Add SEC_lib_Open inside Entry.c (void entry(void))
//       Show how to load a Pin Key + enter pin + get pinblock.
//       Show how to load a Mac Key + get Mac on a message.
//                                                                            
//  List of routines in file :  
//      PinEntry : Manage the Pin Entry.
//      EncypherPin : Pin encyphered by PIN key.
//      CreateSecret : Secret area creation.
//      FreeSecret : Secret area deletion.
//      LoadPinKey : Load Pin Key inside the secret area.
//      LoadMacKey : Load Mac Key inside the secret area.  
//      GetConfig : Configuration of the security component. 
//      PinEntryIso9564 : manage the Pin entry to get the Pinblock.
//      MacCalculation : manage the Mac on a message.                                    
//                            
//  File history :
//  120508-BK : File created 
//                                                                           
//****************************************************************************

//****************************************************************************
//      INCLUDES                                                            
//****************************************************************************

//#include "incs.h"

#include "SDK30.H"
#include  "crypto_def.h"
#include <SEC_interface.h>
#include <schVar_def.h>
#ifdef _DEPRECATED_SDK71_
#include "deprecated.h"
#endif


#include "_emvdctag_.h"
#include "_emvdc_.h"
#include "del_lib.h"		
#include "bitmap.h"
#include "servcust.h"

#include <fm_interApp.h>
#include <fm_proto.h>
#include <fm_HMIService.h>
#include <fm_genpinpad.h>
#include "crypto_lib.h"
/*
#ifdef ID_DATA
#undef ID_DATA
#endif
*/
#include <tlvVar_def.h>

/*
#include "SDK30.H"
#include "SEC_interface.h"
#include "schVar_def.h"	// scheme includes
#include "tlvVar_def.h"
#include "Training.h"
*/
//****************************************************************************
//      EXTERN                                                              
//****************************************************************************
    /* */

unsigned char						BypassPin;
//****************************************************************************
//      PRIVATE CONSTANTS                                                   
//****************************************************************************
#define __KARTUKU_PROD__

#ifdef __KARTUKU_PROD__

#ifdef __SMART_2__
#define VAR_NUMBER_SIGN	    0x0070
#define CARD_NUMBER_SIGN    0x0002A772
#define ID_SCR_BNI_BANK	    0x27012130	//secret area for BNI
#else
#define VAR_NUMBER_SIGN	    0x0140
#define CARD_NUMBER_SIGN    0x100006A3
#define ID_SCR_BNI_BANK	    0x01402131	//secret area for BNI
#endif

#else
#define VAR_NUMBER_SIGN	    0x00
#define CARD_NUMBER_SIGN    0x0003C009
#define ID_SCR_XXX_BANK	    0x0E012130
#endif

#define CHECK(CND,LBL) {if(!(CND)){goto LBL;}}


#define C_NB_PARTS	3

#define INTERN_BOOSTER_PRODUCT "TERMINAL"
#define EXTERN_BOOSTER_PRODUCT "PINPAD"

#ifdef __KARTUKU_PROD__
// ROOT KEY offset
#define BNI_ROOT_KEY_NO_126				1008    // (126 slot)

// PIN MASTER KEY offset
#define BNI_MASTER_KEY_NO_009			72		// (9 slot)
// PIN KEY offset 
#ifdef __SMART_2__
#define BNI_PIN_KEY_NO_013				8     // (13 slot)
#else
#define BNI_PIN_KEY_NO_013				104     // (13 slot)
#endif
// MAC KEY NUMBER
//#define BNI_MAC_KEY_NO_011				88      // (11 slot)

#ifdef _BRI_APP_
#define BRI_MASTER_KEY_NO_001			4		// (9 slot)
#define BRI_PIN_KEY_NO_017				136		// (9 slot)


#define ID_BRI_BANK_MASTER_KEY 			ID_KEY_DES(0x80000000, 0x00000001)	// ID_BNI_BANK_MASTER_KEY * 4 = BNI_MASTER_KEY_NO_009
#define ID_BRI_BANK_PIN_KEY 			ID_KEY_DES(0x80000000, 0x00000022)	// ID_BNI_BANK_MASTER_KEY * 4 = BNI_MASTER_KEY_NO_009

#endif

// BANK ID TO USE 
#define ID_BNI_BANK_MASTER_KEY 			ID_KEY_TDES(0x80010000, 0x00000012)	// ID_BNI_BANK_MASTER_KEY * 4 = BNI_MASTER_KEY_NO_009

#ifdef __SMART_2__
#define ID_BNI_BANK_PIN_KEY				ID_KEY_TDES(0x80020000, 0x00000002) // ID_BNI_BANK_PIN_KEY * 4 = BNI_PIN_KEY_NO_013
#else
#define ID_BNI_BANK_PIN_KEY				ID_KEY_TDES(0x80020000, 0x0000001A) // ID_BNI_BANK_PIN_KEY * 4 = BNI_PIN_KEY_NO_013
#endif

//this is additional offset for support multi MK & EWK, limited to 5 different MK & EWk in one secret area, RFU
#define NO_MK_2							0x22
#define NO_WK_2							0x2A
#define MASTER_KEY_NO_017				136	//slot 17, MK 2
#define WORKING_KEY_NO_021			168	//slot 21, EWK 2
#define ID_BANK_MASTER_KEY_2			ID_KEY_TDES(0x80030000, NO_MK_2)
#define ID_BANK_PIN_KEY_2				ID_KEY_TDES(0x80040000, NO_WK_2) 

#define NO_MK_3							0x32
#define NO_WK_3							0x3A
#define MASTER_KEY_NO_025				200	//slot 25, MK 3
#define WORKING_KEY_NO_029			232	//slot 29, WK 3
#define ID_BANK_MASTER_KEY_3			ID_KEY_TDES(0x80050000, NO_MK_3)
#define ID_BANK_PIN_KEY_3				ID_KEY_TDES(0x80060000, NO_WK_3) 

#define NO_MK_4							0x42
#define NO_WK_4							0x4A
#define MASTER_KEY_NO_033				264	//slot 33, MK 4
#define WORKING_KEY_NO_037			296	//slot 37, WK 4
#define ID_BANK_MASTER_KEY_4			ID_KEY_TDES(0x80070000, NO_MK_4)
#define ID_BANK_PIN_KEY_4				ID_KEY_TDES(0x80080000, NO_WK_4) 

#define NO_MK_5							0x52
#define NO_WK_5							0x5A
#define MASTER_KEY_NO_041				328	//slot 41, MK 5
#define WORKING_KEY_NO_045			360	//slot 45, WK 5
#define ID_BANK_MASTER_KEY_5			ID_KEY_TDES(0x80090000, NO_MK_5)
#define ID_BANK_PIN_KEY_5				ID_KEY_TDES(0x80100000, NO_WK_5) 

#else

#define PIN_MASTER_KEY_NO_XXX			72
#define PIN_KEY_NO_XXX					104

#define ID_BANK_MASTER_KEY			ID_KEY_TDES(0x80010000, 0x00000012)
#define ID_BANK_PIN_KEY				ID_KEY_TDES(0x80020000, 0x0000001A) 
#define ID_BANK_XXX						BK_SAGEM

#endif
//****************************************************************************
//      PRIVATE TYPES                                                       
//****************************************************************************
    /* */

//****************************************************************************
//      PRIVATE DATA                                                        
//****************************************************************************
//const unsigned char TheRootKey[DES_KEY_SIZE]		=	{0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37};//[TDES_KEY_SIZE+1] ="\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37";//[TDES_KEY_SIZE+1] "\x11\x11\x11\x11\x11\x11\x11\x11\x22\x22\x22\x22\x22\x22\x22\x22";
//const unsigned char ThePinMasterKey [DES_KEY_SIZE] =	{0x9B, 0x38, 0x32, 0x53, 0xBD, 0x7D, 0x3E, 0x84};//"\x40\xB3\x9B\xA8\x55\xE0\x41\x16"; // unciphered is 4343434343434343
const unsigned char ThePinKey[TDES_KEY_SIZE]		=	{0xC2, 0x7B, 0xFF, 0xAC, 0xD4, 0x43, 0x6B, 0x1B, 0x02, 0xB4, 0x06, 0xB4, 0x3C, 0xDB, 0x30, 0xBE};//{0x5E, 0x06, 0x6F, 0x1D, 0x59, 0x98, 0x81, 0xF3, 0x5E, 0x06, 0x6F, 0x1D, 0x59, 0x98, 0x81, 0xF3};//{0xC2, 0x7B, 0xFF, 0xAC, 0xD4, 0x43, 0x6B, 0x1B};//{0x50, 0x91, 0x9F, 0x45, 0x11, 0xCE, 0xE1, 0x10};
//=====================================================================================================

/** 
 * function: GetBoosterType 
 * @brief: Return booster type of terminal 
 * @author: JC. Pommaret 
 * @return: 1 for booster1, 2 for booster2, ... 
 */



//const unsigned char TheMacMasterKey [DES_KEY_SIZE] = "\x27\xB6\xA9\x4E\x50\xD4\xFA\x45";  // unciphered is 0923456789ABCDEF
//const unsigned char TheRootKey1[DES_KEY_SIZE]=          {0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43};
//const unsigned char TheRootKey [TDES_KEY_SIZE+1] = "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11";
//const unsigned char ThePinMasterKey [DES_KEY_SIZE]  = "\x42\x25\xEA\x8E\x9A\x0B\x5F\x63"; // unciphered is 6B218F24DE7DC66C  */


//****************************************************************************
//             int PinEntry (const char *msg, bool ppad)                            
//  This function manages the pin entry.      
//       SEC_PinEntryInit : To initialise the parameters for the secure 
//                          Pin entry code
//       SEC_PinEntry : To manage the secure pincode entry
//  This function has parameters.
//     msg (I-) : Message to display
//     ppad (I-) :   0 = Pin entry on termial, 1 = Pin entry on Pin Pad    
//  This function has return value.
//     0 : Pin entry done or timeout
//     others : Pin entry failed                                              
//****************************************************************************


void set_star(char *o_pc_buf, int i_l_len)
{
    int i;
    for (i = 0; i < i_l_len; i++)
        o_pc_buf[i] = '*';
    o_pc_buf[i] = 0;
}


static int GetBoosterType(void) 
{ 
	FILE * iapp;
	char data[3+1];

	iapp = fopen("IAPP","rw*");
	if((iapp != NULL) || (stdperif("IAPP",NULL) != NULL))
	{
		if(iapp != NULL) fclose(iapp);
		
		SystemFioctl(SYS_FIOCTL_GET_PRODUCT_CODE,data); 
		if(memcmp(data,"M35",3) > 0) 
		{ 
			return(2); 
		} 
		else          
		{ 
			return(1); 
		}
	}
	else
	{
		return(0);
	}
}


int SetConfigSecurity     (void)
{
	T_SEC_CONFIG tabConfParts;//[C_NB_PARTS];//for this moment only for PIN entry
	int  iret, iNbParts, ibPinpadBoost, icrChoice;//i, iind,
	char cBoosterType, cBoosterTypePinpad;//, * ptTitleSeclect;
	//char * tab_choice[2];

	icrChoice = CR_ENTRY_OK;
	if (GetBoosterType () >= 2)
		cBoosterType = C_SEC_BL2;
	else
		cBoosterType = C_SEC_BL1;

	cBoosterTypePinpad = C_SEC_BL1;
	ibPinpadBoost = FALSE;
	iret = PSQ_Is_pinpad();
	if (iret != 0)
	{
		iret = PSQ_Pinpad_Value();
		switch (iret)
		{
			case PP30_PPAD:
			case PPC30_PPAD:
			case PPR30_PPAD:
			case P30_PPAD:			
				ibPinpadBoost = TRUE;
				cBoosterTypePinpad = C_SEC_BL1;
				if (iret == P30_PPAD)
					cBoosterTypePinpad = C_SEC_BL2;
				break;
			default :
			break;
		}
	}

	tabConfParts.SecureType =	C_SEC_PINCODE; //sctabtypeparts [i];
	tabConfParts.cBoosterType = cBoosterType;
	tabConfParts.ptszBoosterPeripheral = IAPP_DEF_NAME;
	tabConfParts.cbGestResid = TRUE;

	if (ibPinpadBoost == TRUE)
		{//assumption, does external pinpad exist
		tabConfParts.ptszBoosterPeripheral = IAPP_USB_NAME;
		tabConfParts.cBoosterType = cBoosterTypePinpad;
		}

	iNbParts = 1;//C_NB_PARTS;//set only for C_SEC_PINCODE

	iret = SEC_SetConfig (iNbParts, &tabConfParts);
	
	return (iret);
}


static int EntryPIN (const char *msg, bool ppad)
{
	unsigned int Key;
	unsigned char EndEnterPIN=FALSE;
	unsigned int Indice, Column, Line;
	int ihid_key, ibToContinue;
	unsigned int uiEventToWait;
	int ret;
	unsigned char ucdataout;
	char 	szpinpad[20];
	T_SEC_ENTRYCONF stEntryConfig;

	//@me, 20 Agustus 2010
	unsigned char ThePan[12+1], pinOK;

	memset(ThePan, 0x00, sizeof(ThePan));
	//@me, eof

	Column= 5; Line= 1;
	EndEnterPIN= FALSE;
	Indice= 0;
	szpinpad [0] = 0;
	

	//if (!ppad) {
	//	printf("\x1b"); printf(msg); }
	//else {
	if(ppad)
		PPS_firstline (); PPS_Display ((char*) msg);// }


	// timeOut first char: 60000 ms, other 10000 ms, HidKey : 0x2A
	// get Pin ( 4 to 10 digits)
	ihid_key = 0x2A;
	stEntryConfig.ucEchoChar = (unsigned char) ihid_key;
	stEntryConfig.ucMinDigits = 4;
	stEntryConfig.ucMaxDigits = 6;
	stEntryConfig.iFirstCharTimeOut = 30*1000;
	stEntryConfig.iInterCharTimeOut = 10*1000;
	ret = SEC_PinEntryInit (&stEntryConfig, C_SEC_PINCODE); CHECK(ret==OK, lblKO);

	if (!ppad) 
		uiEventToWait=0; 
	else 
		uiEventToWait = KEYBOARD;                   // waiting event EFT keyboard while Pinpad Entry

	ibToContinue = TRUE;
    while(EndEnterPIN != TRUE)
	{
		ret = SEC_PinEntry (&uiEventToWait, &ucdataout, &ibToContinue);
		{
			if (ret==OK)
			{
				Key = ucdataout;
				
				if (!ppad)
					uiEventToWait = 0;
				else
					uiEventToWait = KEYBOARD;       // waiting event EFT keyboard 

				if (Key == (unsigned int) ihid_key)
				{
					if (Indice < MAX_PIN_CODE_SIZE) 
					{
						if (Indice == 0) 
						{
							if (!ppad) 
							{
								//gotoxy(Line, Column); 
								//printf("               ");
								
								set_star(ThePan, Indice);
								//set_star(ThePan, Indice+1);//@me, 23 agustus 2010
								pp_display_text(4, 8, ThePan, PT_ALIGN_LEFT|PT_CLEAR);
							}
							else 
							{
								PPS_newline ();
								PPS_clearline ();
								PPS_Display ("               "); 
								szpinpad[0] =0;
							}
						}

						if (!ppad) 
						{
							//gotoxy(Line, Column+Indice); printf("%c", Key);
							//set_star(ThePan, Indice);
							set_star(ThePan, Indice+1);
							pp_display_text(4, 8, ThePan, PT_ALIGN_LEFT|PT_CLEAR);
						}
						else
						{
							szpinpad[Indice] = Key;
							szpinpad[Indice+1] = 0;
							PPS_clearline ();
							PPS_Display (szpinpad); 
						}
						Indice++;
					} 
					else 
					{
						EndEnterPIN = TRUE;  // To stop 
					}
				}
				else 
				{
					switch (Key) 
					{
					case 0x00: // TimeOut 
					case 0x01: // Response to stop the PinEntry 
						ret = ERR_TIMEOUT;
						break;
					case T_VAL :
						pinOK = TRUE;
						EndEnterPIN = TRUE;
						if(Indice == 0)	// no pin entered !!
						{
							BypassPin = TRUE;
						}
						break;
					case T_ANN: // CANCELL
						ret = ERR_ENTRY_CANCELED;  // ERR_TIMEOUT;
						break;
					case T_CORR:
						if (Indice!=0) 
						{
							Indice--;
							if (!ppad)
							{
								//gotoxy(Line, Column+Indice); printf(" ");
								
								set_star(ThePan, Indice);
								pp_display_text(4, 8, ThePan, PT_ALIGN_LEFT|PT_CLEAR);
							}
							else
							{
								PPS_clearline ();
								szpinpad[Indice] = 0;
								PPS_Display (szpinpad); 
							}
						}
						break;
					}
				}
			}
			else if (ret == ERR_TIMEOUT)
				EndEnterPIN = TRUE;
			else if (ret == ERR_ENTRY_CANCELED)// imam for handleing Cancel
				EndEnterPIN = TRUE;
			
			else
				EndEnterPIN = TRUE;
		}
			
		if (ibToContinue  == FALSE)
			EndEnterPIN = TRUE;   // End of while 
		else if (EndEnterPIN == TRUE)
		{
			ibToContinue = FALSE; // To stop the PIN Entry
			EndEnterPIN = FALSE;  // in the loop of while 
		}
	}

	if (ppad)
		PPS_clear_display();

lblKO:
	return (ret);			
}

//****************************************************************************
//                          void EncipherPin (void)                            
//  This function encyphers the Pin entry by using the PIN key loaded in the
//  secret area.       
//       SEC_Iso9564() : ISO 9564 Pin cyphering  (ANSI X9.8)
//  This function has no parameters.    
//  This function has no return value.                                      
//****************************************************************************

int EncipherPIN	(unsigned char *acc, unsigned char *blk)
{
	// Local variables 
    // ***************
	unsigned int uiLengthOut;
	T_SEC_PARTTYPE SecPart;
	T_SEC_DATAKEY_ID stKey;
	int ret, iFormat;
//	uint8 i;

    // ISO9564 Pin ciphering
	// *********************
	SecPart = C_SEC_PINCODE;                  // Secure part used to store the PIN key 
#ifdef __KARTUKU_PROD__

	#ifdef BRI_DEBIT
  stKey.iSecretArea = ID_SCR_KARTUKU;//ID_SCR_BNI_BANK;//ID_SCR_XXX_BANK;
	stKey.usNumber = BRI_PIN_KEY_NO_017;//BNI_PIN_KEY_NO_013;
	stKey.uiBankId = ID_BRI_BANK_PIN_KEY;//ID_BNI_BANK_PIN_KEY;//ID_BANK_XXX;
	#else
  stKey.iSecretArea = ID_SCR_BNI_BANK;//ID_SCR_XXX_BANK;
       stKey.usNumber = BNI_PIN_KEY_NO_013;//BNI_PIN_KEY_NO_013;
	stKey.uiBankId = ID_BNI_BANK_PIN_KEY;//ID_BNI_BANK_PIN_KEY;//ID_BANK_XXX;
	#endif
#else
	stKey.iSecretArea = ID_SCR_XXX_BANK;//ID_SCR_XXX_BANK;
	stKey.usNumber = PIN_KEY_NO_XXX;
	stKey.uiBankId = ID_BANK_PIN_KEY;//ID_BANK_XXX;
#endif
#ifdef BRI_DEBIT
	stKey.cAlgoType = TLV_TYPE_KDES;//TLV_TYPE_KTDES;          // PIN key is a DES Key 
	
	iFormat = ISO9564_F0_DES;//ISO9564_F0_TDES;
#else
	stKey.cAlgoType = TLV_TYPE_KTDES;          // PIN key is a DES Key 
	
	iFormat = ISO9564_F0_TDES;
#endif
/*
	ret=pprintf("Account Number:\n");
	for (i=0; i<8; i++)
	{
		ret = pprintf ("%02x ", *(acc+i));
	}
*/

	ret = SEC_Iso9564 (C_SEC_PINCODE, &stKey, iFormat, (unsigned char *) acc,
					   (unsigned char *)blk, &uiLengthOut);

/*
	pprintf("return val %d Pin Blok:\n", ret);
	for (i=0; i<8; i++)
	{
		pprintf ("%02x ", *(blk+i));
	}
	pprintf("PiBlk length : %d \n\n", uiLengthOut);
*/

	return (ret);
}


#ifndef __KARTUKU_PROD__
//****************************************************************************
//                          void CreateSecret (void)                            
//  This function creates a secret area and loads the Root key.      
//       SEC_CreateSecretArea() : To create a secret area
//       SEC_LoadKey() : To load a key in secret area
//  This function has no parameters.    
//  This function has no return value.                                      
//****************************************************************************

void CreateSecret (uint8 * msTerKey)
{
	// Local variables 
    // ***************
	byte dspHdr=1;
	T_SEC_DATAKEY_ID stRootKey;
	int iUsage;
	int ret;

	// Change font size
	// ================
	dspHdr = StateHeader(0);                                 // Disable EFT930 header
    font_size (8,16);                                        // Normal font size
	putchar('\x1B');                                         // Clear screen

    ret=DLLExist("SECURITY"); CHECK(ret==TRUE, lblNoSecDll); // Security DLL loaded?    
	ret=printf("CreateSecretArea"); CHECK(ret>=0, lblKO);    // Display message

    // Create Secret Area
	// ******************
	ret = SEC_CreateSecretArea (C_SEC_CIPHERING,//C_SEC_PINCODE,               // Secure type
				                (SEG_ID) ID_SCR_XXX_BANK, 
								CARD_NUMBER_SIGN, 
								VAR_NUMBER_SIGN); CHECK(ret==OK, lblKO);
	
	// Load Root Key
	// *************
	stRootKey.iSecretArea = ID_SCR_XXX_BANK;
	stRootKey.cAlgoType   = TLV_TYPE_KTDES;                  // This ROOT key is a TDES Key
	stRootKey.usNumber    = PIN_MASTER_KEY_NO_XXX;//ROOT_KEY_NO_XXX;
	stRootKey.uiBankId      =ID_BANK_XXX;// ID_BANK_MASTER_KEY;//
	iUsage = CIPHERING_KEY;                                  // Key to cipher PIN key or MAC key 
	ret = SEC_LoadKey (C_SEC_CIPHERING,  
					   NULL, &stRootKey, (unsigned char*) msTerKey, iUsage); CHECK(ret==OK, lblKO_CIPHERING);


    gotoxy(1,0);
	ret=printf("Area done..."); CHECK(ret>=0, lblKO);        // Display message
    ttestall(0,3*100);                                       // Delay 3s 

	goto lblEnd;

	// Errors treatment 
    // ****************
lblNoSecDll:
	putchar('\x1B');                                         // Clear screen
	printf("Missing Sec DLL ");                              // Security DLL missing
	ttestall(0,5*100);                                       // Delay 5s 
	goto lblEnd;
lblKO_CIPHERING:
	putchar('\x1B');                                         // Clear screen
	printf("CIPHERING Error");                              // Oops! error
    ttestall(0,5*100);                                       // Delay 5s 
    goto lblEnd;
lblKO:
	putchar('\x1B');                                         // Clear screen
	printf("Processing Error");                              // Oops! error
    ttestall(0,5*100);                                       // Delay 5s 
lblEnd:
    StateHeader(dspHdr);                                     // Enable EFT930 header
}

int InjectMK(void)
{
	char tmp[34];
	uint8 tmphex[20];
	int ret;

	memset(tmp, 0, sizeof tmp);

	pp_display_clear(0);

	if(IsPasswordOK(prtSecurityCode, PASS_SECURITY_CODE, 6) != ING_SUCCESS)
		return 0;

//	if (KeyboardEntry(prtMasterInjection, tmp,16, 16, KBD_LINE_4, TIMEOUT_T) == ING_FAIL) return;

	
	//pp_settittle("GPRS SETTING");
	pp_display_clear(0);
	pp_display_text(2, 0, "MASTER KEY", PT_ALIGN_LEFT|PT_CLEAR);
	ret=pp_keyboard_entry_free(tmp, 16, 16,KBD_LINE_3 |KBD_COL_1|KBD_DISPLAY_ALPHA,TIMEOUT);
	if (ret<1)
		return 0;
	
	tmp[16] = 0x00;
	memset(tmphex, 0x00, sizeof(tmphex));
	//Aschex(tmphex, tmp, 16);
	
	A_asctobcd(tmp, tmphex, 16);

	//because Triple Des
	memcpy(&tmphex[8], tmphex, 8);

	
	CreateSecret(tmphex);
	return 1;
}

#endif
//****************************************************************************
//                          void FreeSecret (void)                            
//  This function is used to kill the secret area.      
//       SEC_FreeSecret() : To free a secret data or the whole secret area.
//  This function has no parameters.    
//  This function has no return value.                                      
//****************************************************************************
#if 0
void FreeSecret (void)
{
	// Local variables 
    // ***************
	byte dspHdr=1;
	T_SEC_DATAKEY_ID stEraseKey;
	int ret;

	pp_display_clear(0);
#ifdef PASS_GEN
	if (GetSecurityKey()==STOP)
		return;
#else		
	
	if(IsPasswordOK(prtSecurityCode, 337346, 6) != ING_SUCCESS)
		return;
	pp_display_clear(0);
	if(IsPasswordOK(prtSecurityCode, 263862, 6) != ING_SUCCESS)
		return;
#endif


	// Change font size
	// ================
	dspHdr = StateHeader(0);                                 // Disable EFT930 header
    font_size (8,16);                                        // Normal font size
	putchar('\x1B');                                         // Clear screen

    ret=DLLExist("SECURITY"); CHECK(ret==TRUE, lblNoSecDll); // Security DLL loaded?    
	ret=printf("FreeSecretArea"); CHECK(ret>=0, lblKO);      // Display message

	// Erase Secret Area
	// *****************
#ifdef __KARTUKU_PROD__
	#ifdef BRI_DEBIT
	stEraseKey.iSecretArea =ID_SCR_KARTUKU;//ID_SCR_BNI_BANK;
  #else
  	stEraseKey.iSecretArea =ID_SCR_BNI_BANK;
  #endif
#else
	stEraseKey.iSecretArea = ID_SCR_XXX_BANK;
#endif
	stEraseKey.cAlgoType = 0;
	stEraseKey.usNumber = 0;
	stEraseKey.uiBankId = 0;
    ret = SEC_FreeSecret (C_SEC_PINCODE, &stEraseKey); 

#ifdef __SMART_2__
	{
	char tmpsaja[16+1];
	memset(tmpsaja, 0x00, sizeof(tmpsaja));
	sprintf(tmpsaja, "ret val : %d", ret);
	printf(tmpsaja);
	ttestall(0,3*100);     
	}
#endif 

	CHECK(ret==OK, lblKO);

    gotoxy(1,0);
	ret=printf("Area free..."); CHECK(ret>=0, lblKO);        // Display message
	ttestall(0,3*100);                                       // Delay 3s 

	goto lblEnd;

	// Errors treatment 
    // ****************
lblNoSecDll:
	putchar('\x1B');                                         // Clear screen
	printf("Missing Sec DLL ");                              // Security DLL missing
	ttestall(0,5*100);                                       // Delay 5s 
	goto lblEnd;
lblKO:
	putchar('\x1B');                                         // Clear screen
	printf("Processing Error");                              // Oops! error
    ttestall(0,5*100);                                       // Delay 5s 
lblEnd:
    StateHeader(dspHdr);                                     // Enable EFT930 header   
}

#endif
//****************************************************************************
//                          void LoadPinKey (void)                            
//  This function loads the Pin key inside the secret area by using the Root key. 
//       SEC_LoadKey() : To load a key in secret area
//  This function has no parameters.    
//  This function has no return value.                                      
//****************************************************************************

void LoadPinKey (unsigned char * EncryptedWorkingKEY)
{
	// Local variables 
    // ***************
	byte dspHdr=1;
	T_SEC_DATAKEY_ID stRootKey, stPinMasterKey, stPinKey;
	int iUsage;
	int ret;

	memset(&stRootKey, 0x00, sizeof(T_SEC_DATAKEY_ID));
	memset(&stPinMasterKey, 0x00, sizeof(T_SEC_DATAKEY_ID));
	memset(&stPinKey, 0x00, sizeof(T_SEC_DATAKEY_ID));

	// Change font size
	// ================
	dspHdr = StateHeader(0);                                 // Disable EFT930 header
    font_size (8,16);                                        // Normal font size
	putchar('\x1B');                                         // Clear screen

    ret=DLLExist("SECURITY"); CHECK(ret==TRUE, lblNoSecDll); // Security DLL loaded?    
	ret=printf("LoadPinKey"); CHECK(ret>=0, lblKO);          // Display message

	// Load Pin Key using Root Key
	// ***************************
	//declaration of root key previous create
/*	stRootKey.iSecretArea = ID_SCR_XXX_BANK;
	stRootKey.cAlgoType   = TLV_TYPE_KDES;                  // This ROOT key is a TDES Key 
	stRootKey.usNumber    = ROOT_KEY_NO_XXX;
	stRootKey.uiBankId      = ID_BANK_XXX;
*/
#ifdef __KARTUKU_PROD__

#ifdef BRI_DEBIT
	stPinMasterKey.iSecretArea =ID_SCR_KARTUKU;//ID_SCR_BNI_BANK;
	stPinMasterKey.usNumber = BRI_MASTER_KEY_NO_001;//BNI_MASTER_KEY_NO_009;//PIN_MASTER_KEY_NO_XXX;
	stPinMasterKey.uiBankId = ID_BRI_BANK_MASTER_KEY;//ID_BNI_BANK_MASTER_KEY;//ID_BANK_XXX;
	#else
	stPinMasterKey.iSecretArea =ID_SCR_BNI_BANK;
	stPinMasterKey.usNumber = BNI_MASTER_KEY_NO_009;//BNI_MASTER_KEY_NO_009;//PIN_MASTER_KEY_NO_XXX
	stPinMasterKey.uiBankId = ID_BNI_BANK_MASTER_KEY;//ID_BNI_BANK_MASTER_KEY;//ID_BANK_XXX;
#endif	
#else
	stPinMasterKey.iSecretArea = ID_SCR_XXX_BANK;
	stPinMasterKey.usNumber = PIN_MASTER_KEY_NO_XXX;//PIN_MASTER_KEY_NO_XXX;
	stPinMasterKey.uiBankId = ID_BANK_MASTER_KEY;//ID_BANK_XXX;
#endif
#ifdef BRI_DEBIT
	stPinMasterKey.cAlgoType = TLV_TYPE_KDES;//TLV_TYPE_KTDES;;//TLV_TYPE_KTDES;
  #else
	stPinMasterKey.cAlgoType = TLV_TYPE_KTDES;;//TLV_TYPE_KTDES;
#endif
	
/*	iUsage = CIPHERING_KEY;
	ret = SEC_LoadKey(C_SEC_PINCODE, 
					   &stRootKey, &stPinMasterKey, (unsigned char*)&ThePinMasterKey, iUsage);
	CHECK(ret==OK, lblKOPinMasterKey);
*/
#ifdef __KARTUKU_PROD__

	#ifdef BRI_DEBIT
  	stPinKey.iSecretArea = ID_SCR_KARTUKU;//ID_SCR_BNI_BANK;
	stPinKey.usNumber = BRI_PIN_KEY_NO_017;//BNI_PIN_KEY_NO_013;
	stPinKey.uiBankId = ID_BRI_BANK_PIN_KEY;//ID_BNI_BANK_PIN_KEY;//ID_BANK_XXX;
	#else
  	stPinKey.iSecretArea = ID_SCR_BNI_BANK;
	stPinKey.usNumber = BNI_PIN_KEY_NO_013;//BNI_PIN_KEY_NO_013;
	stPinKey.uiBankId = ID_BNI_BANK_PIN_KEY;//ID_BNI_BANK_PIN_KEY;//ID_BANK_XXX;

	#endif
#else
	stPinKey.iSecretArea = ID_SCR_XXX_BANK;
	stPinKey.usNumber = PIN_KEY_NO_XXX;
	stPinKey.uiBankId = ID_BANK_PIN_KEY;//ID_BANK_XXX;
#endif
#ifdef BRI_DEBIT
	stPinKey.cAlgoType = TLV_TYPE_KDES;//TLV_TYPE_KTDES;                      // This PIN key is a DES Key 
#else
	stPinKey.cAlgoType = TLV_TYPE_KTDES; 
#endif
	iUsage = CIPHERING_PIN;                                  // Key to cipher PIN entry 
	ret = SEC_LoadKey (C_SEC_PINCODE,  
					   &stPinMasterKey, &stPinKey, (unsigned char*)((EncryptedWorkingKEY == NULL)? ThePinKey : EncryptedWorkingKEY), iUsage);

#ifdef __SMART_2__
		if(EncryptedWorkingKEY)
			{
			char tmpsaja[20];
			memset(tmpsaja, 0x00, sizeof(tmpsaja));
			bcdtoasc(EncryptedWorkingKEY, tmpsaja, 16);
			xx_printf("EPIN : %s",tmpsaja);
			printf(tmpsaja);
			ttestall(0,3*100); 
			}
		xx_printf("ret val : %d", ret);
#endif 

	CHECK(ret==OK, lblKO);
//pprintf("ID MASTER KEY: %x \n", stPinMasterKey.uiBankId);
//ttestall(0,100);                                       // Delay 3s 

//	pprintf("ID PIN KEY: %x \n", stPinKey.uiBankId);
//	ttestall(0,100);                                       // Delay 3s 

    gotoxy(1,0);
	ret=printf("Key loaded..."); CHECK(ret>=0, lblKO);       // Display message
    ttestall(0,3*100);                                       // Delay 3s 



	goto lblEnd;

	// Errors treatment 
    // ****************
lblNoSecDll:
	putchar('\x1B');                                         // Clear screen
	printf("Missing Sec DLL ");                              // Security DLL missing
	ttestall(0,5*100);                                       // Delay 5s 
	goto lblEnd;	
lblKO:
	putchar('\x1B');                                         // Clear screen
	printf("Processing Error");                              // Oops! error
    ttestall(0,3*100);                                       // Delay 3s 
lblEnd:
    StateHeader(dspHdr);                                     // Enable EFT930 header   
}

#if (0)
//****************************************************************************
//                          void LoadMacKey (void)                            
//  This function loads the Mac key inside the secret area by using the Root key.
//       SEC_LoadKey() : To load a key in secret area
//  This function has no parameters.    
//  This function has no return value.                                      
//****************************************************************************

void LoadMacKey (void)
{
	// Local variables 
    // ***************
	byte dspHdr=1;
	T_SEC_DATAKEY_ID stRootKey, stMacKey;
	int iUsage;
	int ret;

	// Change font size
	// ================
	dspHdr = StateHeader(0);                                 // Disable EFT930 header
    font_size (8,16);                                        // Normal font size
	putchar('\x1B');                                         // Clear screen

    ret=DLLExist("SECURITY"); CHECK(ret==TRUE, lblNoSecDll); // Security DLL loaded?    
	ret=printf("LoadMacKey"); CHECK(ret>=0, lblKO);          // Display message

	// Load Mac Key using Root Key
	// ***************************
	stRootKey.iSecretArea = ID_SCR_XXX_BANK;
	stRootKey.cAlgoType   = TLV_TYPE_KTDES;                  // This ROOT key is a TDES Key 
	stRootKey.usNumber    = ROOT_KEY_NO_XXX;
	stRootKey.uiBankId      = ID_BANK_XXX;

	stMacKey.iSecretArea = ID_SCR_XXX_BANK;
	stMacKey.cAlgoType = TLV_TYPE_KDES;                      // This MAC key is a DES Key 
	stMacKey.usNumber = MAC_KEY_NO_XXX;
	stMacKey.uiBankId = ID_BANK_XXX;

	iUsage = CIPHERING_DATA;                                 // Key to cipher Data Message  
	ret = SEC_LoadKey (C_SEC_CIPHERING,  
					   &stRootKey, &stMacKey, (unsigned char*) &TheMacMasterKey, iUsage);
	CHECK(ret==OK, lblKO);

    gotoxy(1,0);
	ret=printf("Key loaded..."); CHECK(ret>=0, lblKO);       // Display message
    ttestall(0,3*100);                                       // Delay 3s 

	goto lblEnd;

	// Errors treatment 
    // ****************
lblNoSecDll:
	putchar('\x1B');                                         // Clear screen
	printf("Missing Sec DLL ");                              // Security DLL missing
	ttestall(0,5*100);                                       // Delay 5s 
	goto lblEnd;	
lblKO:
	putchar('\x1B');                                         // Clear screen
	printf("Processing Error");                              // Oops! error
    ttestall(0,3*100);                                       // Delay 3s 
lblEnd:
    StateHeader(dspHdr);                                     // Enable EFT930 header
}
#endif

//****************************************************************************
//                          void GetConfig (void)                            
//  This function gets the configuration of the security component for the 
//  current application.      
//       SET_GetConfig() : Configuration of the security component.
//       SEC_listSecureId() : List Ids of loaded schemes and secret areas
//                            in a secure part.
//  This function has no parameters.    
//  This function has no return value.                                      
//****************************************************************************
#if 0
void GetConfig (void)
{

	// Local variables 
    // ***************
	byte dspHdr=1;
	int NbParts;
	T_SEC_CONFIG tabConfParts[C_NB_PARTS];
	int NbId, tabList[10];
	int i, i1, ret;

	pp_display_clear(0);
#ifdef PASS_GEN
	if (GetSecurityKey()==STOP)
		return;
#else		
	if(IsPasswordOK(prtSecurityCode, 337346, 6) != ING_SUCCESS)
		return;
	pp_display_clear(0);
	if(IsPasswordOK(prtSecurityCode, 263862, 6) != ING_SUCCESS)
		return;
#endif

	// Change font size
	// ================
	dspHdr = StateHeader(0);                                       // Disable EFT930 header
    font_size (8,16);                                              // Normal font size
	putchar('\x1B');                                               // Clear screen

    ret=DLLExist("SECURITY"); CHECK(ret==TRUE, lblNoSecDll);       // Security DLL loaded?
	ret=printf("Info Security..."); CHECK(ret>=0, lblKO);          // Display message

	// Get the configuration of the security component
	// ===============================================
    ret = SEC_GetConfig(&NbParts, tabConfParts); CHECK(ret==OK, lblKO);
	ret = pprintf ("Nbr secure parts: %d\n", NbParts); CHECK(ret>=0, lblKO);
    for (i=0; i<NbParts; i++)
	{
		switch (tabConfParts[i].SecureType)
		{
		case C_SEC_PINCODE:   ret = pprintf("\n-PIN ENTRY: ");   break;  
		case C_SEC_CARD:      ret = pprintf("\n-CARD READER: "); break;
		case C_SEC_CIPHERING: ret = pprintf("\n-CIPHERING: ");   break;
		default:              ret = pprintf("\n-SecurePart: %d ", tabConfParts[i].SecureType); break; 
		}
		CHECK(ret>=0, lblKO);
		if ( memcmp (tabConfParts[i].ptszBoosterPeripheral, IAPP_USB_NAME, strlen(IAPP_USB_NAME)) == 0)
		{
			ret = pprintf(EXTERN_BOOSTER_PRODUCT); CHECK(ret>=0, lblKO);
		}
		else
		{
			ret = pprintf(INTERN_BOOSTER_PRODUCT); CHECK(ret>=0, lblKO);
		}
		if ( tabConfParts[i].cBoosterType == C_SEC_BL2 )
		{
			ret = pprintf("\nBooster Type=2\n"); CHECK(ret>=0, lblKO);
		}
		else
		{
			ret = pprintf("\nBooster Type=1\n"); CHECK(ret>=0, lblKO);
		}
		if ( tabConfParts[i].cbGestResid == TRUE )
		{
			ret = pprintf("Resident schemes enable\n"); CHECK(ret>=0, lblKO);
		}
		else
		{
			ret = pprintf("Resident schemes disable\n"); CHECK(ret>=0, lblKO);
		}

		// Get the list of Ids of loaded schemes and secret areas in a secure part
		// =======================================================================
		memset (tabList, 0, sizeof(tabList)); NbId=0;
		ret = SEC_listSecureId (tabConfParts[i].SecureType, &NbId, tabList); CHECK(ret==OK, lblKO);
		ret = pprintf ("Secret Area Ids:\n"); CHECK(ret>=0, lblKO);
		for (i1=0; i1<NbId; i1++)
		{
			ret = pprintf ("%08x\n", tabList[i1]); CHECK(ret>=0, lblKO);
		}
	}

	ret = pprintf("\n\n\n\n\n\n"); CHECK(ret>=0, lblKO);

	goto lblEnd;

	// Errors treatment 
    // ****************
lblNoSecDll:
	putchar('\x1B');                                             // Clear screen
	printf("Missing Sec DLL ");                                  // Security DLL missing
	ttestall(0,5*100);                                           // Delay 5s 
	goto lblEnd;
lblKO:
	putchar('\x1B');                                             // Clear screen
	printf("Processing Error");                                  // Oops! error
    ttestall(0,3*100);                                           // Delay 3s 
lblEnd:
	ttestall(PRINTER, 2*100);   
    StateHeader(dspHdr);                                         // Enable EFT930 header   
}
#endif

#if (0)
//****************************************************************************
//                          void PinEntryIso9564 (void)                            
//  This function manages the Pin entry to get the Pinblock.      
//  This function has no parameters.    
//  This function has no return value.                                      
//****************************************************************************

int PinEntryIso9564 (TRANSACTION_DATA *pTransactionData)
{
	// Local variables 
    // ***************	
	byte dspHdr=1;
	char* msg;
	byte acc[8];
    byte blk[8];
	int i, ret;
	uint8 PANLength, track2[41], PANs[16];

BypassPin = FALSE;
	// Change font size
	// ================
	dspHdr = StateHeader(0);                                       // Disable EFT930 header
    font_size (8,16);                                              // Normal font size
	putchar('\x1B');                                               // Clear screen

    ret=DLLExist("SECURITY"); CHECK(ret==TRUE, lblNoSecDll);       // Security DLL loaded?    
	ret=printf("Pin Entry..."); CHECK(ret>=0, lblKO);              // Display message

    // Enter PIN
	// *********
	msg = "AMOUNT= 1000 EUR\nPIN:\n";
	ret = PinEntry (msg, FALSE); CHECK(ret!=ERR_TIMEOUT, lblEnd);
	CHECK(ret==OK, lblKO);

	// PIN ciphering and pinblock calculation
	// **************************************
	PANLength = (uint8)crdGetPANLength(pTransactionData->Iso.Track2);
	crdUnpackTrack2(track2, pTransactionData->Iso.Track2);

	memset(PANs, 0x00, sizeof PANs);
	memcpy(PANs, track2, PANLength);
	memset(track2, 0x00, sizeof(track2));
	memcpy(&track2[4], &PANs[3], 12);
	memcpy(track2, "0000", 4);
	memset(PANs, 0x00, sizeof(PANs));
	//crdPackTrack2(PANs, track2, 16);
	asctobcd(track2, PANs, 16);
	//	PANs[PANLength] = 0;		
	//PANLength = (uint8)crdGetPANLength(pTransactionData->Iso.Track2);
	if(PANLength % 2)PANLength++;
	
	memcpy(acc, PANs, PANLength/2);
	//memcpy(acc, "\x00\x00\x78\x90\x12\x34\x56\x74", 8);
	ret = EncipherPin ((unsigned char*)acc, (unsigned char*)blk); CHECK(ret==OK, lblKO);
	
	memset(pTransactionData->Iso.PinBlock, 0x00, 8);
	memcpy(pTransactionData->Iso.PinBlock, blk, 8);

	// Print and display pinblock
	// ==========================
    //ret=pprintf("\x1b""E""       Pin Entry Demo\n\n"               // Print demo in progress
//		        "\x1b""F"); CHECK(ret>=0, lblKO);      
/*
    ret=pprintf("Account Number:\n"); CHECK(ret>=0, lblKO);
	for (i=0; i<8; i++)
	{
		ret = pprintf ("%02x ", acc[i]); CHECK(ret>=0, lblKO);
	}
*/
/*	
    ret=pprintf("\nPin Key:\n");CHECK(ret>=0, lblKO);
	for(i=0; i<8; i++)
		{
		ret = pprintf ("%02x ", blk[i]); CHECK(ret>=0, lblKO);
		}
*/	
    ret = pprintf("\nPinblock:\n"); CHECK(ret>=0, lblKO);
	for (i=0; i<8; i++)
	{
		ret = pprintf ("%02X ", blk[i]); CHECK(ret>=0, lblKO);
	}

	ret = pprintf("\n\n\n\n\n\n"); CHECK(ret>=0, lblKO);

	gotoxy(0,0); ret=printf("\x1B""PinBlock:"); CHECK(ret>=0, lblKO);  
	gotoxy(1,0);
	for (i=0; i<8; i++)
	{
		ret = printf ("%02X", blk[i]); CHECK(ret>=0, lblKO);       // Display PinBlock
	}


	ttestall(0,5*100);                                             // Delay 5s
	
	goto lblEnd;

	// Errors treatment 
    // ****************
lblNoSecDll:
	putchar('\x1B');                                               // Clear screen
	printf("Missing Sec DLL ");                                    // Security DLL missing
	ttestall(0,5*100);                                             // Delay 5s 
	return ERR_SYSTEM;
	goto lblEnd;
lblKO:
	putchar('\x1B');                                               // Clear screen
	printf("Processing Error");                                    // Oops! error
    ttestall(0,5*100);                                             // Delay 5s 
    return KO;
lblEnd:  
	ttestall(PRINTER, 10);   
    StateHeader(dspHdr);                                           // Enable EFT930 header   
    return OK;
}

//****************************************************************************
//                          void MacCalculation (void)                            
//  This function manages the Mac calculation on a message.      
//  This function has no parameters.    
//  This function has no return value.                                      
//****************************************************************************

void MacCalculation	(void)
{
	// Local variables 
    // ***************	
	byte dspHdr=1;
    T_SEC_DATAKEY_ID stMacKey;
	const unsigned char msg [24] = "\x11\x11\x11\x11\x11\x11\x11\x11"
		                           "\x22\x22\x22\x22\x22\x22\x22\x22"
								   "\x33\x33\x33\x33\x33\x33\x33\x33";
    byte mac[8];
	int i, ret;

	// Change font size
	// ================
	dspHdr = StateHeader(0);                                     // Disable EFT930 header
    font_size (8,16);                                            // Normal font size
	putchar('\x1B');                                             // Clear screen

    ret=DLLExist("SECURITY"); CHECK(ret==TRUE, lblNoSecDll);     // Security DLL loaded?
	ret=printf("Mac Compute..."); CHECK(ret>=0, lblKO);          // Display message

    // Mac calculation
	// ***************
	stMacKey.iSecretArea = ID_SCR_XXX_BANK;
	stMacKey.cAlgoType = TLV_TYPE_KDES;                          // MAC key is a DES Key 
	stMacKey.usNumber = MAC_KEY_NO_XXX;
	stMacKey.uiBankId = ID_BANK_XXX;
	ret = SEC_ComputeMAC (&stMacKey, (unsigned char *) msg, sizeof(msg),
						  NULL, mac); CHECK(ret==0, lblKO)

	// Print and display Mac
	// =====================
    ret=pprintf("\x1b""E""        MAC Demo\n\n"                  // Print demo in progress
		        "\x1b""F"); CHECK(ret>=0, lblKO);      
    ret=pprintf("Data message:\n"
		        "11 11 11 11 11 11 11 11\n"
				"22 22 22 22 22 22 22 22\n"
				"33 33 33 33 33 33 33 33\n"); CHECK(ret>=0, lblKO);
	ret=pprintf("MAC Key:\n"
		        "09 23 45 67 89 AB CD EF\n"); CHECK(ret>=0, lblKO);
    ret = pprintf("Mac calculation:\n"); CHECK(ret>=0, lblKO);
	for (i=0; i<8; i++)
	{
		ret = pprintf ("%02X ", mac[i]); CHECK(ret>=0, lblKO);
	}

	ret = pprintf("\n\n\n\n\n\n"); CHECK(ret>=0, lblKO);

	gotoxy(0,0); ret=printf("\x1B""Mac:"); CHECK(ret>=0, lblKO); // Display PinBlock
	gotoxy(1,0);
	for (i=0; i<8; i++)
	{
		ret = printf ("%02X", mac[i]); CHECK(ret>=0, lblKO);
	}

	ttestall(0,5*100);                                           // Delay 5s
	
	goto lblEnd;

	// Errors treatment 
    // ****************
lblNoSecDll:
	putchar('\x1B');                                             // Clear screen
	printf("Missing Sec DLL ");                                  // Security DLL missing
    ttestall(0,5*100);                                           // Delay 5s 
	goto lblEnd;
lblKO:
	putchar('\x1B');                                             // Clear screen
	printf("Processing Error");                                  // Oops! error
    ttestall(0,5*100);                                           // Delay 5s 
lblEnd:
	ttestall(PRINTER, 10);   
    StateHeader(dspHdr);                                         // Enable EFT930 header   
}
#endif

uint8 CS_StatusSSM(void)
{
	if(DLLExist("SECURITY")==TRUE)
		return TRUE;
	return FALSE;
}

// Check whether the security area is exist
// Return: TRUE/FALSE
uint8 CS_FindAlloc(void)
{
//	CS_StatusSSM();

#ifdef __KARTUKU_PROD__
#ifdef BRI_DEBIT
	if(SEC_isSecretArea (C_SEC_PINCODE, ID_SCR_KARTUKU)==OK)//ID_SCR_BNI_BANK
#else
	if(SEC_isSecretArea (C_SEC_PINCODE, ID_SCR_BNI_BANK)==OK)
#endif
#else
	if(SEC_isSecretArea (C_SEC_PINCODE, ID_SCR_XXX_BANK)==OK)
#endif
		return TRUE;

//    _trace("CS_FindAlloc: End");
    return FALSE;
}


void   asctobcd(char const* src, uint8* dest, uint8 num_digits)
{
	Aschex(dest,(byte*)src,num_digits);
}

int CS_PIN(unsigned char * PinBlock,unsigned char * cardNo, int cardNoLen)
{

//	uint8 PANLength, track2[41], PANs[16];
	unsigned char reformatPAN[8];
	unsigned char tmpPAN[12];
       int  ret=0;
	   ret=EntryPIN(NULL, FALSE);

	if(ret==OK)
		{
			//initialize
			memset(reformatPAN, 0x00, sizeof(reformatPAN));
			memset(tmpPAN, 0x00, sizeof(tmpPAN));
			
			//copy the PAN, by following the PIN BLOCK Format 1
			memcpy(tmpPAN, cardNo+3, 12);
			//repack the PAN, for generate Pin Block
			asctobcd( tmpPAN, &reformatPAN[2], 12);

			if(EncipherPIN(reformatPAN, PinBlock)==OK)
				return ERR_PIN_SUCCESS;
		}
	else if (ret==ERR_TIMEOUT)
		return ERR_PIN_TIMEOUT;
	else if  (ret==ERR_ENTRY_CANCELED)
		  return ERR_PIN_CANCEL;
	return ERR_PIN_SUCCESS;
}


//============================================================================================================

uint8 iccIsKeyLoaded(void)
{
	if(CS_StatusSSM())
		return(CS_FindAlloc());
	
	return FALSE;
}


int iccEncrypt(uint8 *PINBlock, uint8 *CrdPAN, uint8 CrdLen)
{
//	if( iccIsKeyLoaded() )	//in the parent function that called this function, iccIskeyLoaded was called too, therefore, i think there is no need to calling the same function again
//		{
			pp_display_text(3, 0, "PIN :", PT_ALIGN_LEFT);
                      return   CS_PIN(PINBlock, CrdPAN, CrdLen)  ;
//			return ((CS_PIN(PINBlock, CrdPAN, CrdLen)==OK)? TRUE : FALSE);
//		}
	
//	return FALSE;
}


//=====================================================================================================================

uint8 crdUnpackTrack2(uint8 *dest, uint8 *src)
{
	uint8 count;

	for(count=0;;)
	{
		dest[count++] = ((*src & 0xf0) >> 4) | 0x30;
		if (count > 36)
			break;

		dest[count++] = (*src++ & 0x0f) | 0x30;
	}

	return(count);
}

//uint8 PinEntry(TRANSACTION_DATA *pTransactionData)

int  PinEntry(unsigned char * datatrack2, unsigned char *pinblock )

{
	char dispLine[22];
	uint8 PANLength, track2[41], PANs[16];
	unsigned char PinBlock[8]	;
	//_trace3("PinEntry....");
	if( !iccIsKeyLoaded())
		{
		//	errSet(ERR_GE_KEYS_NOT_LOADED);
			pp_display_clear(0);
			pp_display_text(2, 0, "... LOAD EPK ...", PT_ALIGN_CENTER|PT_CLEAR);
			pp_display_text(3, 0, "... FAILED ...", PT_ALIGN_CENTER|PT_CLEAR);
			return ERR_PIN_NOCONFIRM;// ING_FAIL;// push to time Put 
		

		}
		//AO:04052005: move the prompt table to another place
			

		
	//pp_display_prompts(ptrGetPin);
	
	//AO:04052005: End
	pp_display_clear(0);
	//dspIssuerNameTransType(pTransactionData);
	//pp_display_text(2, 0, FormatAmount(pTransactionData->Iso.Amount + pTransactionData->Iso.Tip, NegativeAmount(pTransactionData), dispLine, sizeof(dispLine)), PT_ALIGN_RIGHT);

//	PANLength = (uint8)crdGetPANLength(pTransactionData->Iso.Track2);
//	crdUnpackTrack2(track2, pTransactionData->Iso.Track2);
	PANLength = (uint8)crdGetPANLength(datatrack2);
		crdUnpackTrack2(track2, datatrack2);

	memset(PANs, 0x00, sizeof PANs);
	memcpy(PANs, track2, PANLength);
	PANs[PANLength] = 0;		
	
	//memset(pTransactionData->Iso.PinBlock, 0x00, 8);
	//memset(PinBlock, 0x00, 8);
	return iccEncrypt(pinblock, PANs, PANLength) ;
	#if 0
	if(iccEncrypt(pinblock, PANs, PANLength)==TRUE)

//	if(iccEncrypt(pTransactionData->Iso.PinBlock, PANs, PANLength)==TRUE)
		return  0;//ING_SUCCESS;

	//errSet(ERR_GE_OPERATOR_CANCEL);
	return VK_CANCEL;			
	#endif	
}

//extern uint8 TS_SelectMerchant(prompt_t const* prompts, uint32 *pMerchantID);

//void LoadEPK2SecureArea(void)
void LoadEPK2SecureArea(uint8 * ucEWK)

{
	//=====================================
	/*
	FMFILE * 	 		ExtractorFid;
	prompt_t prompts[4] =
	    {	   
	        {PI_EOF,				PT_ALIGN_CENTER},
	        {0,						0}

	    };
	*/
	//dpmCardRange_t	CardRangeTab;
#if 0 // imam
	int32	 		status;
	uint32 merchantID = 0;
	uint32 prevAcqID = 0xFFFFFFFF, prevIssuerID = 0xFFFFFFFF;
	uint8 * encryptedPinKey;//[8+8+1];
#endif
#if 0 //def __FORCE_WK__
	uint8 force_wk[16+1];
	memset(force_wk, 0x00, sizeof(force_wk));
	memcpy(force_wk, "\x2C\xBC\xEE\xA2\x28\xEF\x6D\x53\x2C\xBC\xEE\xA2\x28\xEF\x6D\x53", 16);
#endif
	//======================================
	//xx_datetime_get((uint32 *)&Date, (uint32 *)&Time);
	//xx_datetime_get(&Date, &Time);

	pp_display_clear(0);
	pp_display_text(2, 0, "... LOAD EPK ...", PT_ALIGN_CENTER|PT_CLEAR);
	pp_display_text(3, 0, "... IF EXIST ...", PT_ALIGN_CENTER|PT_CLEAR);

if(ucEWK != NULL)
		{
		LoadPinKey(ucEWK);
		return;
		}
#if 0
	
#ifndef __FORCE_WK__
#ifdef BRI_DEBIT
	if(ucEWK != NULL)
		{
		LoadPinKey(ucEWK);
		return;
		}
    #endif

	//search the correct issuer ID that enable PIN entry, linked with the acquirer ID
	//retrieve merchant ID, if i'mnot mistake, the MerchantID value is always 1, wakakakak ^_^
	if ((status=TS_SelectMerchant(prompts, &merchantID)) != ING_SUCCESS)
		return;// status;

	//list CARD RANGE
	if( (ExtractorFid = dpmForEachRecord(TABLE_CARD_RANGE)) == 0)
		return;

	while(TRUE)
	{
		memset(&CardRangeTab,0x00,sizeof(CardRangeTab));
		
		status = dpmNextRecord(ExtractorFid, &CardRangeTab, sizeof(CardRangeTab));
		if(status == DB_EXECUTE_OK)
		{//got card range 
			//check the acqID & issuerID to temporary variable
			if( (prevAcqID == CardRangeTab.CreditAcquirerID) || (prevIssuerID == CardRangeTab.CreditIssuerID) )
				{
				}
			else
				{
				//store the acqID & issuerID to temporary variable
				prevAcqID = CardRangeTab.CreditAcquirerID;
				prevIssuerID = CardRangeTab.CreditIssuerID;
				
				//now, check the issuer, is it PIN Entry Enabled
				if(dpmIssuerRecordGet(CardRangeTab.CreditIssuerID)->PinOption == PIN_REQUIRED)
					{
					//yes PIn entry enabled, this is debit
					//get PIN from merchant Table, using Acquirer ID that linked with current Issuer ID, see the card range table
					if(memcmp(dpmMerchantRecordGet(merchantID, CardRangeTab.CreditAcquirerID)->EncryptedPINKey, "\x00\x00\x00\x00\x00\x00\x00\x00", 8)!=0)// EPK set in TMS not NULL, now try to load to secret area
						{

							encryptedPinKey = (uint8*) umalloc( 16+1 );

							//initialize temp EPK buffer
							memset(encryptedPinKey, 0x00, sizeof(encryptedPinKey));

							//copy EPK got from merchant table to temp EPK buffer
							memcpy(encryptedPinKey, dpmMerchantRecordGet(merchantID, CardRangeTab.CreditAcquirerID)->EncryptedPINKey, 8);//DES only, cause TMS only support that
							memcpy(&encryptedPinKey[8], dpmMerchantRecordGet(merchantID, CardRangeTab.CreditAcquirerID)->EncryptedPINKey, 8);//double it to make it see like TDES

							//now load to secret area
							LoadPinKey(encryptedPinKey);
							ufree(encryptedPinKey);

							//cause currently only support one EPK on one terminal
							//after load key, we have to get out
							break;
						}
					}
				}
		}
		else
			break;
	}

	FM_fclose(ExtractorFid);
#else //__FORCE_WK__
	LoadPinKey(force_wk);
#endif
#endif
	pp_get_key(2);
	//end of card range table
}


#endif //_USE_DLL_SECURITY_


